﻿using System;
using System.Collections.Generic;
using System.Linq;
using TuxedoLib;

namespace SpaceSquirrel
{
	public class Context
	{
		private const int START_LIFE = 10;
		private const int FULL_LIFE = 10;
		private const int START_LIVES = 3;
		private const string ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

		public int LifeMeter { get; set; }
		public int Lives { get; set; }
		public bool VolcanoA { get; set; }
		public bool VolcanoB { get; set; }
		public bool VolcanoC { get; set; }
		public bool BalloonA { get; set; }
		public bool BalloonB { get; set; }
		public bool BalloonC { get; set; }
		public bool BalloonD { get; set; }
		public bool Gravity { get; set; }
		public bool Transmission1 { get; set; }
		public bool Transmission2 { get; set; }
		public bool Transmission3 { get; set; }
		public bool Transmission4 { get; set; }

		public Dictionary<string, bool> PowerUpsTaken { get; private set; }

		public Context()
		{
			this.LifeMeter = START_LIFE;
			this.Lives = START_LIVES;
			this.VolcanoA = false;
			this.VolcanoB = false;
			this.VolcanoC = false;
			this.BalloonA = false;
			this.BalloonB = false;
			this.BalloonC = false;
			this.BalloonD = false;
			this.Gravity = false;
			this.Transmission1 = false;
			this.Transmission2 = false;
			this.Transmission3 = false;
			this.Transmission4 = false;
			this.PowerUpsTaken = new Dictionary<string, bool>();
		}

		public string ConvertToPassword()
		{
			int count;
			if (this.BalloonA || this.BalloonB || this.BalloonC || this.BalloonD)
			{
				count = 3;
			}
			else if (this.VolcanoA || this.VolcanoB || this.VolcanoC)
			{
				count = 2;
			}
			else if (this.Gravity)
			{
				count = 1;
			}
			else
			{
				count = 0;
			}

			string password = "";

			if (count == 1)
			{
				password = "A";
			}
			else if (count == 2)
			{
				password = "B";
			}
			else if (count == 3)
			{
				password = "C";
			}
			else
			{
				password = "" + this.RandomChar(ALPHABET, 3, 0);
			}

			if (count >= 1)
			{
				if (this.Gravity)
				{
					password += this.RandomChar(ALPHABET, 0, 13);
				}
				else
				{
					password += this.RandomChar(ALPHABET, 13, 0);
				}
			}
			else
			{
				password += this.RandomChar(ALPHABET, 0, 0);
			}

			if (count >= 2)
			{
				int value = (this.VolcanoA ? 1 : 0) + ((this.VolcanoB ? 1 : 0) * 2) + ((this.VolcanoC ? 1 : 0) * 4);
				char letter = (char)('0' + value);
				password += letter;
			}
			else
			{
				password += this.RandomChar("0123456789", 0, 0);
			}

			if (count >= 3)
			{
				int value = (this.BalloonA ? 1 : 0) + ((this.BalloonB ? 1 : 0) * 2) + ((this.BalloonC ? 1 : 0) * 4) + ((this.BalloonD ? 1 : 0) * 8);
				char letter = (char)('A' + value - 1);
				password += letter;
			}
			else
			{
				password += this.RandomChar(ALPHABET, 0, 0);
			}

			return password;
		}

		private char RandomChar(string pool, int begin, int end)
		{
			if (end == 0)
			{
				end = pool.Length;
			}

			int index = Util.RandomInt(begin, end);
			return pool[index];
		}

		private char EnforceLetter(char letter)
		{
			if (letter < 'A') return 'A';
			if (letter > 'Z') return 'Z';
			return letter;
		}

		private char EnforceNumber(char number)
		{
			if (number < '0') return '0';
			if (number > '9') return '9';
			return number;
		}

		public void ConvertFromPassword(string password)
		{
			char p1 = this.EnforceLetter(password[0]);
			char p2 = this.EnforceLetter(password[1]);
			char p3 = this.EnforceLetter(password[2]);
			char p4 = this.EnforceLetter(password[3]);

			if ("ABC".IndexOf(p1) != -1)
			{
				if (p2 < 'M')
				{
					this.Gravity = true;
				}
			}

			if ("BC".IndexOf(p1) != -1)
			{
				int value = p3 - '0';
				this.VolcanoA = (value & 1) != 0;
				this.VolcanoB = (value & 2) != 0;
				this.VolcanoC = (value & 4) != 0;
			}

			if (p1 == 'C')
			{
				int value = p4 - 'A' + 1;
				this.BalloonA = (value & 1) != 0;
				this.BalloonB = (value & 2) != 0;
				this.BalloonC = (value & 4) != 0;
				this.BalloonD = (value & 8) != 0;
			}

			this.LifeMeter = START_LIFE;
			this.Lives = START_LIVES;
		}

		public Pair<char, int> GetCurrentCountAndType()
		{
			int vcount = (this.VolcanoA ? 1 : 0) + (this.VolcanoB ? 1 : 0) + (this.VolcanoC ? 1 : 0);
			int wcount = (this.BalloonA ? 1 : 0) + (this.BalloonB ? 1 : 0) + (this.BalloonC ? 1 : 0) + (this.BalloonD ? 1 : 0);
			if (this.Gravity)
			{
				if (vcount == 3)
				{
					if (wcount == 4)
					{
						return null; // bird seed
					}
					return new Pair<char, int>('W', wcount);
				}
				return new Pair<char, int>('V', vcount);
			}
			return null; // gravity
		}

		public void AdjustHealth(PlayScene scene, int amount)
		{
			this.LifeMeter += amount;
			if (this.LifeMeter <= 0)
			{
				this.LifeMeter = 0;
				scene.Next = new DeathOverrideScene(scene, "collapse");
			}
			else
			{
				if (amount < 0)
				{
					if (this.LifeMeter < 4)
					{
						SoundManager.PlayNoise("low_health");
					}
					else
					{
						SoundManager.PlayNoise("get_hit");
					}
				}
				else
				{
					SoundManager.PlayNoise("raise_health");
				}
			}

			if (this.LifeMeter > 10)
			{
				this.LifeMeter = 10;
			}
		}
	}
}
